package com.utilities.pipelineScripts;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Element;

import com.utilities.IO.FileUtilities;
import com.utilities.IO.fileWriters.PrepareAllFeaturesFiles;
import com.utilities.dataStructures.Range;
import com.utilities.fastaUtilities.MummerUtilities;
import com.utilities.fastaUtilities.OtherUtilities;
import com.utilities.visualiser.PrepareXMLFile;

public class SNPVisualizer {
	
	private static PrepareXMLFile prepareXMLFile = null;
	private static String[] colors = {"maroon","red","blue","green","orange", "purple","fuchsia","navy",
		"lime","olive","yellow","teal","aqua","silver","gray","white","black"};
	
	public static void main(String args[]) throws Exception
	{
		int i = 0;
		int generations = Integer.parseInt(args[i]);
		int seqLength = Integer.parseInt(args[++i]);
		String vxmlfile = args[++i];
		int threshold = 0;
		
		String[] strs = new String[2];
		strs[0] = "Reference" ; strs[1] = "Accno";
		
		ArrayList<Range> diffs_7328 = fetchDifferences(strs, args[++i],threshold);
		Collections.sort(diffs_7328,new RangeComparator());
		
		ArrayList<Range> diffs_gamma22 = fetchDifferences(strs,args[++i],threshold);
		Collections.sort(diffs_gamma22,new RangeComparator());
		
		
		ArrayList<Range> diffs_gamma52 = fetchDifferences(strs,args[++i],threshold);
		Collections.sort(diffs_gamma52,new RangeComparator());
		
		
		ArrayList<Range> diffs_gamma70 = fetchDifferences(strs,args[++i], threshold);
		Collections.sort(diffs_gamma70,new RangeComparator());
		
		ArrayList<String> snps = FileUtilities.readListFromFile(args[++i]);
		ArrayList<Range> snpRangs_singleEnds  = new ArrayList<Range>();
		
		for (String str : snps)
		{
			int ind = Integer.parseInt(str.split("\t")[0]);
			Range r = new Range(ind, ind, str);
			snpRangs_singleEnds.add(r);
		}
		ArrayList<Range> gaps_singleEnds = MummerUtilities.getGaps(args[++i]);
		++i;
//		PrepareAllFeaturesFiles allFeaturesFiles = new PrepareAllFeaturesFiles();
//		allFeaturesFiles.setGbkFile(args[++i]).setReadReference(false).setCollectGenes(true).run();
//		ArrayList<Range> genes = allFeaturesFiles.toRange(allFeaturesFiles.getGeneMap());
		
		String[] names = new String[generations];
		ArrayList<ArrayList<Range>> ranges = new ArrayList<ArrayList<Range>>();
//		ranges.add(diffs_7328);
//		ranges.add(diffs_gamma22);
//		ranges.add(diffs_gamma52);
		ranges.add(diffs_gamma70);
		ranges.add(snpRangs_singleEnds);
//		ranges.add(genes);
		
		
		int j = 0;
		for(; i + 1 < args.length ; )
		{
			names[j] = args[++i];
			j++;
		}
		String[] names2 = new String[2];
		names2[0] = names[3];
		names2[1] = names[4];
//		names2[2] = names[2];
//		names2[3] = names[3];
//		names2[4] = names[4];
		try
		{
			SNPVisualizer.makeVisualisation(ranges, seqLength, names2, vxmlfile);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private static void makeVisualisation(ArrayList<ArrayList<Range>> ranges,int seqLength,String[] names, String vXml) 
	throws ParserConfigurationException
	{
		initialise(String.valueOf(seqLength),names);
		makeFeatureSlots(names.length);
		int index = 0;
		for (ArrayList<Range> strain : ranges)
		{
			int count = 1;
			for(Range range : strain)
			{
				String mouseOver = "Start = " + String.valueOf(range.getLowerLimit())
				+ ", stop = " + String.valueOf(range.getUpperLimit());
				String name = range.getMetadata().trim();
				if (name.contains("NODE_"))
				{
					String[] temp = name.split("\t");
					mouseOver = mouseOver + ", \n" + temp[1] + " " + temp[2];
				}
				else
				{
					String[] temp = name.split("\t");
					mouseOver = mouseOver + ", \n" + temp[3] + " " + temp[4];
				}
				name = "Diff_" + count;
//				 = range.getMetadata().split("\t")[0];
				Element feature = prepareXMLFile.createFeature("directStrand" +index, colors[index], "clockwise-arrow", 
						name, null,mouseOver,null,null,null);
				prepareXMLFile.createFeatureRange(feature, String.valueOf(range.getLowerLimit()), 
						String.valueOf(range.getUpperLimit()), null);
				count++;
			}
			index++;
		}
		prepareXMLFile.writeToFile(vXml);
	}

	private static void initialise(String seqLength, String[] args) throws ParserConfigurationException 
	{
		prepareXMLFile = new PrepareXMLFile().createCGView(seqLength)
		.createLegend("sideLegend", "upper-right", "SanSerif, plain, 10", "0.8");

		for (int i = 0; i < args.length; i++)
		{
			String legendLabel = args[i];
			prepareXMLFile = prepareXMLFile.createLegendItem("sideLegend", legendLabel, "SanSerif, plain, 12", true, colors[i]);
		}
		prepareXMLFile = prepareXMLFile.createLegend("lowerleftlegend", "lower-left", "SanSerif, plain, 9", "0.8")
		.createLegendItem("lowerleftlegend", "This map was generated using CGView", null, false, null)
		.createLegend("lowerrightlegend", "lower-right", "SanSerif, plain, 9", "0.8")
		.createLegendItem("lowerrightlegend", "Work done at D-BSSE ETH Zurich", null, false, null);
	}

	private static void makeFeatureSlots(int slots) 
	{
		for(int i = 0; i < slots ; i++)
		{
			prepareXMLFile = prepareXMLFile.createFeatureSlots("directStrand" + i, "direct",false);
		}
	}
	
	public static ArrayList<Range> fetchDifferences(String[] filters, String fileName, int threshold) throws Exception {
		Set<String> set = OtherUtilities.fastaHeader(fileName,filters);
		ArrayList<Range> diffs = new ArrayList<Range>();
		for(String d : set)
		{
			String[] params = d.split("\t");
			String coverage = params[6].split("%")[0];
			if (Integer.parseInt(coverage) > threshold)
			{
				Range range = new Range(Integer.parseInt(params[1]), Integer.parseInt(params[2]), d);
				diffs.add(range);
			}
		}
		return diffs;
	}
}
